﻿using Haidou.Wpf.Util.Settings;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Haidou.Wpf.Util
{
	/// <summary>
	/// 将消息存储在磁盘文件中的基本日志编写器。
	/// </summary>
	public static class LogWriter
	{
		/// <summary>
		/// 写细节
		/// </summary>
		/// <param name="writer"></param>
		/// <param name="ex"></param>
		/// <param name="level"></param>
		private static void WriteDetails(TextWriter writer, Exception ex, int level)
		{
			writer.WriteLine(new string('▬', level) + $" Message - {Environment.NewLine}\t{ex.Message}");
			writer.WriteLine(new string('○', level) + $" Type - {Environment.NewLine}\t{ex.GetType()}");
			writer.WriteLine(new string('▲', level) + $" Source - {Environment.NewLine}\t{ex.Source}");
			writer.WriteLine(new string('▼', level) + $" TargetSite - {Environment.NewLine}\t{ex.TargetSite}");

			if (ex is BadImageFormatException bad)
			{
				writer.WriteLine(new string('☼', level) + $" Filename - {Environment.NewLine}\t{bad.FileName}");
				writer.WriteLine(new string('►', level) + $" Fuslog - {Environment.NewLine}\t{bad.FusionLog}");
			}
			else if (ex is ArgumentException arg)
			{
				writer.WriteLine(new string('☼', level) + $" ParamName - {Environment.NewLine}\t{arg.ParamName}");
			}

			if (ex.HelpLink != null)
			{
				writer.WriteLine(new string('◘', level) + $" Other - {Environment.NewLine}\t{ex.HelpLink}");
			}

			writer.WriteLine(new string('♠', level) + $" StackTrace - {Environment.NewLine}{ex.StackTrace}");

			if (ex.InnerException == null || level >= 6)
			{
				return;
			}

			writer.WriteLine();
			WriteDetails(writer, ex.InnerException, level + 1);
		}

		/// <summary>
		///将异常详细信息写入磁盘上的错误日志。
		/// </summary>
		/// <param name="ex">The Exception to write.要写入的异常</param>
		/// <param name="title">The name of the error.错误的名称</param>
		/// <param name="additional">Additional information.附加信息。</param>
		/// <param name="isFallback">Fallbacks to the Documents folder.退回到文档文件夹。</param>
		public static void Log(Exception ex, string title, object? additional = null, bool isFallback = false)
		{
			try
			{
				#region Output folder.输出文件夹

				string documents = AppContext.BaseDirectory;
				string folder = Path.Combine(documents, "Haidou.Desktop", "LogsError");

				if (!Directory.Exists(folder))
				{
					Directory.CreateDirectory(folder);
				}

				#endregion

				#region Creates the file.创建文件

				string date = Path.Combine(folder, DateTime.Now.ToString("yyyy_MM_dd") + ".txt");
				string dateTime = Path.Combine(folder, DateTime.Now.ToString("yyyy_MM_dd hh_mm_ss_fff") + ".txt");

				FileStream fs = null;
				bool inUse = false;

				try
				{
					fs = new FileStream(date, FileMode.OpenOrCreate, FileAccess.ReadWrite);
				}
				catch (Exception)
				{
					inUse = true;
					fs = new FileStream(dateTime, FileMode.OpenOrCreate, FileAccess.ReadWrite);
				}

				fs.Dispose();

				#endregion

				#region Append the exception information.追加异常信息

				using (FileStream fileStream = new(inUse ? dateTime : date, FileMode.Append, FileAccess.Write))
				{
					using (StreamWriter writer = new(fileStream))
					{
						writer.WriteLine($"► Title - {Environment.NewLine}\t{title}");
						writer.WriteLine(FormattableString.Invariant($"♦ [Version] Date/Hour - {Environment.NewLine}\t[{UserSettings.All?.VersionText}] {DateTime.Now}"));

						if (additional != null)
						{
							writer.WriteLine($"◄ Additional.额外的 - {Environment.NewLine}\t{additional}");
						}

						WriteDetails(writer, ex, 1);

						writer.WriteLine();
						writer.WriteLine("----------------------------------");
						writer.WriteLine();
					}
				}

				#endregion
			}
			catch (Exception)
			{
				//One last trial.最后一次审判。
				if (!isFallback)
				{
					Log(ex, title, additional, true);
				}
			}
		}

		/// <summary>
		/// 将详细信息写入磁盘上的错误日志。
		/// </summary>
		/// <param name="title">The name of the error.错误的名称</param>
		/// <param name="additional">Additional information  附加说明.</param>
		/// <param name="secondAdditional">Additional information 附加说明.</param>
		/// <param name="isFallback">Fallbacks to the Documents folder.退回到文档文件夹</param>
		public static void Log(string title, object? additional = null, object? secondAdditional = null, bool isFallback = false)
		{
			try
			{
				#region Output folder

				///获取程序集解析程序用来探测的基目录的文件路径
				//对于程序集。
				string documents = AppContext.BaseDirectory;
				string folder = Path.Combine(documents, "Haidou.Desktop", "Logs");

				if (!Directory.Exists(folder))
				{
					Directory.CreateDirectory(folder);
				}

				#endregion

				#region Creates the file

				string date = Path.Combine(folder, DateTime.Now.ToString("yyyy_MM_dd") + ".txt");
				string dateTime = Path.Combine(folder, DateTime.Now.ToString("yyyy_MM_dd hh_mm_ss_fff") + ".txt");

				FileStream fs = null;
				bool inUse = false;

				try
				{
					fs = new FileStream(date, FileMode.OpenOrCreate, FileAccess.ReadWrite);
				}
				catch (Exception)
				{
					inUse = true;
					fs = new FileStream(dateTime, FileMode.OpenOrCreate, FileAccess.ReadWrite);
				}

				fs.Dispose();

				#endregion

				#region Append the exception information

				using (FileStream fileStream = new(inUse ? dateTime : date, FileMode.Append, FileAccess.Write))
				{
					using (StreamWriter writer = new(fileStream))
					{
						writer.WriteLine($"► Title - {Environment.NewLine}\t{title}");
						writer.WriteLine(FormattableString.Invariant($"♦ [Version] Date/Hour - {Environment.NewLine}\t[{UserSettings.All?.VersionText}] {DateTime.Now}"));

						if (additional != null)
						{
							writer.WriteLine($"◄ Additional.额外的 - {Environment.NewLine}\t{additional}");
						}

						if (secondAdditional != null)
						{
							writer.WriteLine($"◄ Second Additional.第二附加 - {Environment.NewLine}\t{secondAdditional}");
						}

						writer.WriteLine();
						writer.WriteLine("----------------------------------");
						writer.WriteLine();
					}
				}

				#endregion
			}
			catch (Exception)
			{
				//One last trial.
				if (!isFallback)
				{
					Log(title, additional, secondAdditional, true);
				}
			}
		}


		/// <summary>
		/// 将详细信息写入磁盘上的错误日志。语音日志
		/// </summary>
		/// <param name="title">The name of the error</param>
		/// <param name="additional">Additional information  附加说明.</param>
		/// <param name="secondAdditional">Additional information 附加说明.</param>
		/// <param name="isFallback">Fallbacks to the Documents folder.退回到文档文件夹</param>
		public static void SpeechSoundLog(string title, object? additional = null, object? secondAdditional = null, bool isFallback = false)
		{
			try
			{
				#region Output folder

				string documents = AppContext.BaseDirectory;
				string folder = Path.Combine(documents, "Haidou.Desktop", "SpeechSoundLogs");

				if (!Directory.Exists(folder))
				{
					Directory.CreateDirectory(folder);
				}

				#endregion

				#region Creates the file

				string date = Path.Combine(folder, DateTime.Now.ToString("yyyy_MM_dd") + ".txt");
				string dateTime = Path.Combine(folder, DateTime.Now.ToString("yyyy_MM_dd hh_mm_ss_fff") + ".txt");

				FileStream fs = null;
				bool inUse = false;

				try
				{
					fs = new FileStream(date, FileMode.OpenOrCreate, FileAccess.ReadWrite);
				}
				catch (Exception)
				{
					inUse = true;
					fs = new FileStream(dateTime, FileMode.OpenOrCreate, FileAccess.ReadWrite);
				}

				fs.Dispose();

				#endregion

				#region Append the exception information

				using (FileStream fileStream = new(inUse ? dateTime : date, FileMode.Append, FileAccess.Write))
				{
					using (StreamWriter writer = new(fileStream))
					{
						writer.WriteLine($"► Title - {Environment.NewLine}\t{title}");
						writer.WriteLine(FormattableString.Invariant($"♦ [Version] Date/Hour - {Environment.NewLine}\t[{UserSettings.All?.VersionText}] {DateTime.Now}"));

						if (additional != null)
						{
							writer.WriteLine($"◄ Additional.额外的 - {Environment.NewLine}\t{additional}");
						}

						if (secondAdditional != null)
						{
							writer.WriteLine($"◄ Second Additional.第二附加 - {Environment.NewLine}\t{secondAdditional}");
						}

						writer.WriteLine();
						writer.WriteLine("----------------------------------");
						writer.WriteLine();
					}
				}

				#endregion
			}
			catch (Exception)
			{
				//One last trial.
				if (!isFallback)
				{
					Log(title, additional, secondAdditional, true);
				}
			}
		}

		/// <summary>
		/// 将详细信息写入磁盘上的错误日志。操作日志
		/// </summary>
		/// <param name="title">The name of the error</param>
		/// <param name="additional">Additional information  附加说明.</param>
		/// <param name="secondAdditional">Additional information 附加说明.</param>
		/// <param name="isFallback">Fallbacks to the Documents folder.退回到文档文件夹</param>
		public static void OperationLog(string title, object? additional = null, object? secondAdditional = null, bool isFallback = false)
		{
			try
			{
				#region Output folder

				string documents = AppContext.BaseDirectory;
				string folder = Path.Combine(documents, "Haidou.Desktop", "OperationLogs");

				if (!Directory.Exists(folder))
				{
					Directory.CreateDirectory(folder);
				}

				#endregion

				#region Creates the file

				string date = Path.Combine(folder, DateTime.Now.ToString("yyyy_MM_dd") + ".txt");
				string dateTime = Path.Combine(folder, DateTime.Now.ToString("yyyy_MM_dd hh_mm_ss_fff") + ".txt");

				FileStream fs = null;
				bool inUse = false;

				try
				{
					fs = new FileStream(date, FileMode.OpenOrCreate, FileAccess.ReadWrite);
				}
				catch (Exception)
				{
					inUse = true;
					fs = new FileStream(dateTime, FileMode.OpenOrCreate, FileAccess.ReadWrite);
				}

				fs.Dispose();

				#endregion

				#region Append the exception information

				using (FileStream fileStream = new(inUse ? dateTime : date, FileMode.Append, FileAccess.Write))
				{
					using (StreamWriter writer = new(fileStream))
					{
						writer.WriteLine($"► Title - {Environment.NewLine}\t{title}");
						writer.WriteLine(FormattableString.Invariant($"♦ [Version] Date/Hour - {Environment.NewLine}\t[{UserSettings.All?.VersionText}] {DateTime.Now}"));

						if (additional != null)
						{
							writer.WriteLine($"◄ Additional.额外的 - {Environment.NewLine}\t{additional}");
						}

						if (secondAdditional != null)
						{
							writer.WriteLine($"◄ Second Additional.第二附加 - {Environment.NewLine}\t{secondAdditional}");
						}

						writer.WriteLine();
						writer.WriteLine("----------------------------------");
						writer.WriteLine();
					}
				}

				#endregion
			}
			catch (Exception)
			{
				//One last trial.
				if (!isFallback)
				{
					Log(title, additional, secondAdditional, true);
				}
			}
		}


		/// <summary>
		/// 实时扫描---
		/// </summary>
		/// <param name="title"></param>
		/// <param name="additional"></param>
		/// <param name="secondAdditional"></param>
		/// <param name="isFallback"></param>
		public static void RealTimeScanningLog(string title, object? additional = null, object? secondAdditional = null, bool isFallback = false)
		{
			try
			{
				#region Output folder

				string documents = AppContext.BaseDirectory;
				string folder = Path.Combine(documents, "Haidou.Desktop", "RealTimeScanningLogs");

				if (!Directory.Exists(folder))
				{
					Directory.CreateDirectory(folder);
				}

				#endregion

				#region Creates the file

				string date = Path.Combine(folder, DateTime.Now.ToString("yyyy_MM_dd") + ".txt");
				string dateTime = Path.Combine(folder, DateTime.Now.ToString("yyyy_MM_dd hh_mm_ss_fff") + ".txt");

				FileStream fs = null;
				bool inUse = false;

				try
				{
					fs = new FileStream(date, FileMode.OpenOrCreate, FileAccess.ReadWrite);
				}
				catch (Exception)
				{
					inUse = true;
					fs = new FileStream(dateTime, FileMode.OpenOrCreate, FileAccess.ReadWrite);
				}

				fs.Dispose();

				#endregion

				#region Append the exception information

				using (FileStream fileStream = new(inUse ? dateTime : date, FileMode.Append, FileAccess.Write))
				{
					using (StreamWriter writer = new(fileStream))
					{
						writer.WriteLine($"► Title - {Environment.NewLine}\t{title}");
						writer.WriteLine(FormattableString.Invariant($"♦ [Version] Date/Hour - {Environment.NewLine}\t[{UserSettings.All?.VersionText}] {DateTime.Now}"));

						if (additional != null)
						{
							writer.WriteLine($"◄ Additional.额外的 - {Environment.NewLine}\t{additional}");
						}

						if (secondAdditional != null)
						{
							writer.WriteLine($"◄ Second Additional.第二附加 - {Environment.NewLine}\t{secondAdditional}");
						}

						writer.WriteLine();
						writer.WriteLine("----------------------------------");
						writer.WriteLine();
					}
				}

				#endregion
			}
			catch (Exception)
			{
				//One last trial.
				if (!isFallback)
				{
					Log(title, additional, secondAdditional, true);
				}
			}
		}


		/// <summary>
		/// 将详细信息写入磁盘上的错误日志。操作日志
		/// </summary>
		/// <param name="title">The name of the error</param>
		/// <param name="additional">Additional information  附加说明.</param>
		/// <param name="secondAdditional">Additional information 附加说明.</param>
		/// <param name="isFallback">Fallbacks to the Documents folder.退回到文档文件夹</param>
		public static void ProcessingSpeechLog(string title, object? additional = null, object? secondAdditional = null, bool isFallback = false)
		{
			try
			{
				#region Output folder

				string documents = AppContext.BaseDirectory;
				string folder = Path.Combine(documents, "Haidou.Desktop", "ProcessingSpeechLogs");

				if (!Directory.Exists(folder))
				{
					Directory.CreateDirectory(folder);
				}

				#endregion

				#region Creates the file

				string date = Path.Combine(folder, DateTime.Now.ToString("yyyy_MM_dd") + ".txt");
				string dateTime = Path.Combine(folder, DateTime.Now.ToString("yyyy_MM_dd hh_mm_ss_fff") + ".txt");

				FileStream fs = null;
				bool inUse = false;

				try
				{
					fs = new FileStream(date, FileMode.OpenOrCreate, FileAccess.ReadWrite);
				}
				catch (Exception)
				{
					inUse = true;
					fs = new FileStream(dateTime, FileMode.OpenOrCreate, FileAccess.ReadWrite);
				}

				fs.Dispose();

				#endregion

				#region Append the exception information

				using (FileStream fileStream = new(inUse ? dateTime : date, FileMode.Append, FileAccess.Write))
				{
					using (StreamWriter writer = new(fileStream))
					{
						writer.WriteLine($"► Title - {Environment.NewLine}\t{title}");
						writer.WriteLine(FormattableString.Invariant($"♦ [Version] Date/Hour - {Environment.NewLine}\t[{UserSettings.All?.VersionText}] {DateTime.Now}"));

						if (additional != null)
						{
							writer.WriteLine($"◄ Additional.额外的 - {Environment.NewLine}\t{additional}");
						}

						if (secondAdditional != null)
						{
							writer.WriteLine($"◄ Second Additional.第二附加 - {Environment.NewLine}\t{secondAdditional}");
						}

						writer.WriteLine();
						writer.WriteLine("----------------------------------");
						writer.WriteLine();
					}
				}

				#endregion
			}
			catch (Exception)
			{
				//One last trial.
				if (!isFallback)
				{
					Log(title, additional, secondAdditional, true);
				}
			}
		}

		private static readonly object _lock = new();


		/// <summary>
		/// 将详细信息写入磁盘上的错误日志。操作日志 蓝牙的
		/// </summary>
		/// <param name="title">The name of the error</param>
		/// <param name="additional">Additional information  附加说明.</param>
		/// <param name="secondAdditional">Additional information 附加说明.</param>
		/// <param name="isFallback">Fallbacks to the Documents folder.退回到文档文件夹</param>
		public static void BLELog(string title, object? additional = null, object? secondAdditional = null, bool isFallback = false)
		{
			try
			{
				lock (_lock)
				{

					#region Output folder

					string documents = AppContext.BaseDirectory;
					string folder = Path.Combine(documents, "Haidou.Desktop", "BleLogs");

					if (!Directory.Exists(folder))
					{
						Directory.CreateDirectory(folder);
					}

					#endregion

					#region Creates the file

					string date = Path.Combine(folder, DateTime.Now.ToString("yyyy_MM_dd") + ".txt");
					string dateTime = Path.Combine(folder, DateTime.Now.ToString("yyyy_MM_dd hh_mm_ss_fff") + ".txt");

					FileStream fs = null;
					bool inUse = false;

					try
					{
						fs = new FileStream(date, FileMode.OpenOrCreate, FileAccess.ReadWrite);
					}
					catch (Exception)
					{
						inUse = true;
						fs = new FileStream(dateTime, FileMode.OpenOrCreate, FileAccess.ReadWrite);
					}

					fs.Dispose();

					#endregion

					#region Append the exception information

					using (FileStream fileStream = new(inUse ? dateTime : date, FileMode.Append, FileAccess.Write))
					{
						using (StreamWriter writer = new(fileStream))
						{
							writer.WriteLine($"► Title - {Environment.NewLine}\t{title}");
							writer.WriteLine(FormattableString.Invariant($"♦ [Version] Date/Hour - {Environment.NewLine}\t[{UserSettings.All?.VersionText}] {DateTime.Now}"));

							if (additional != null)
							{
								writer.WriteLine($"◄ Additional.额外的 - {Environment.NewLine}\t{additional}");
							}

							if (secondAdditional != null)
							{
								writer.WriteLine($"◄ Second Additional.第二附加 - {Environment.NewLine}\t{secondAdditional}");
							}

							writer.WriteLine();
							writer.WriteLine("----------------------------------");
							writer.WriteLine();
						}
					}

					#endregion

				}

			}
			catch (Exception)
			{
				//One last trial.
				if (!isFallback)
				{
					Log(title, additional, secondAdditional, true);
				}
			}
		}

		/// <summary>
		/// 将详细信息写入磁盘上的错误日志。操作日志 蓝牙的
		/// </summary>
		/// <param name="title">The name of the error</param>
		/// <param name="additional">Additional information  附加说明.</param>
		/// <param name="secondAdditional">Additional information 附加说明.</param>
		/// <param name="isFallback">Fallbacks to the Documents folder.退回到文档文件夹</param>
		public static void SDKLog(string title, object? additional = null, object? secondAdditional = null, bool isFallback = false)
		{
			try
			{
				lock (_lock)
				{

					#region Output folder

					string documents = AppContext.BaseDirectory;
					string folder = Path.Combine(documents, "Haidou.Desktop", "SDKLogs");

					if (!Directory.Exists(folder))
					{
						Directory.CreateDirectory(folder);
					}

					#endregion

					#region Creates the file

					string date = Path.Combine(folder, DateTime.Now.ToString("yyyy_MM_dd") + ".txt");
					string dateTime = Path.Combine(folder, DateTime.Now.ToString("yyyy_MM_dd hh_mm_ss_fff") + ".txt");

					FileStream fs = null;
					bool inUse = false;

					try
					{
						fs = new FileStream(date, FileMode.OpenOrCreate, FileAccess.ReadWrite);
					}
					catch (Exception)
					{
						inUse = true;
						fs = new FileStream(dateTime, FileMode.OpenOrCreate, FileAccess.ReadWrite);
					}

					fs.Dispose();

					#endregion

					#region Append the exception information

					using (FileStream fileStream = new(inUse ? dateTime : date, FileMode.Append, FileAccess.Write))
					{
						using (StreamWriter writer = new(fileStream))
						{
							writer.WriteLine($"► Title - {Environment.NewLine}\t{title}");
							writer.WriteLine(FormattableString.Invariant($"♦ [Version] Date/Hour - {Environment.NewLine}\t[{UserSettings.All?.VersionText}] {DateTime.Now}"));

							if (additional != null)
							{
								writer.WriteLine($"◄ Additional.额外的 - {Environment.NewLine}\t{additional}");
							}

							if (secondAdditional != null)
							{
								writer.WriteLine($"◄ Second Additional.第二附加 - {Environment.NewLine}\t{secondAdditional}");
							}

							writer.WriteLine();
							writer.WriteLine("----------------------------------");
							writer.WriteLine();
						}
					}

					#endregion

				}

			}
			catch (Exception)
			{
				//One last trial.
				if (!isFallback)
				{
					Log(title, additional, secondAdditional, true);
				}
			}
		}


		/// <summary>
		/// 删除
		/// </summary>
		/// <param name="directoryPath"></param>
		public static void DeleteDirectory(string directoryPath)
		{
			try
			{

				// 检查路径是否存在
				if (!Directory.Exists(directoryPath))
				{
					Debug.WriteLine($"Directory {directoryPath} does not exist.");
					return;
				}


				// 递归删除目录和其内容
				foreach (string child in Directory.GetFiles(directoryPath))
				{
					File.Delete(child);
					Debug.WriteLine($"Deleted file: {child}");
				}

				foreach (string child in Directory.GetDirectories(directoryPath))
				{
					DeleteDirectory(child);
					Debug.WriteLine($"Deleted directory: {child}");
				}

				Directory.Delete(directoryPath, true); // 参数true表示删除空目录
				Debug.WriteLine($"Deleted directory: {directoryPath}");
			}
			catch (UnauthorizedAccessException ex)
			{
				Debug.WriteLine(ex.Message);
			}
			catch (Exception ex)
			{
				Debug.WriteLine($"An error occurred: {ex.Message}");
			}
		}





	}
}
